'use strict';

const bcrypt = require('bcryptjs');
const { Service } = require('egg');
const { Op } = require('sequelize');
const dayjs = require('dayjs');
class UserService extends Service {
    /**
     * 根据分页和搜索条件获取用户信息
     * @param {Object} where 查询用户的条件
     * @param {Number} page 当前分页
     * @param {Number} pageSize 当前页每页多少条
     */
    async getUserRolePermissions(where, page, pageSize) {
        const { Member } = this.ctx.model;
        return Member.findAndCountAll({
            attributes: { exclude: ['password'] },
            where: {
                ...where,
                del_flag: 0,
            },
            order:[
                // id 降序
                ['create_time','DESC']
            ],
            offset: pageSize * (page - 1),
            limit: pageSize,
        });
    }
    // 所有列表
    async allList(where={}) {
        const { Member } = this.ctx.model;
        return Member.findAll({
            where: {
                ...where,
                del_flag: 0,
            },
            order:[
                // id 降序
                ['create_time','DESC']
            ],
        });
    }
    /**
     * 注册用户数据
     * @param {Object} data
     */
    async registerUser(data) {
        const { Member } = this.ctx.model;
        if (!data.username) {
            throw new Error('请输入账号');
        }
        const userExists = await Member.findOne({
            attributes: ['id'],
            where: {
                username: data.username,
            },
        });
        if (userExists) throw new Error('该账号已经存在');
        const newUser = await Member.create(data);
        return newUser.dataValues;
    }

    /**
     * 登录
     * @param {Object} user
     */
    async login({ username, password }) {
        const { Member } = this.ctx.model;
        // 根据手机号查询用户是否存在
        let user = await Member.findOne({
            where: { username },
        });
        if (!user) throw new Error('账号不存在');
        // 判断密码是否有误
        const isValid = user.password === password
        if (!isValid) {
            throw new Error('密码错误');
        }
        user = user.dataValues;
        delete user.password;
        return user;
    }

    async findOne(id) {
        const res = await this.ctx.model.Member.findOne({
            where: {
                id,
            },
        });
        // 我的鱼获
        const fishList = await this.ctx.service.fishCatch.allList({
            member_id: id,
        })
        // 我的花费
        const costList = await this.ctx.service.cost.allList({
            member_id: id,
        });
        // 我的打龟
        const turtleList = await this.ctx.service.turtle.allList({
            member_id: id,
        })
        // 我的一起玩
        const playList = await this.ctx.service.play.allList({
            member_id: id,
        })

        return {
            ...res.dataValues,
            my_fish: fishList.length,
            my_cost: costList.length,
            my_data: turtleList.length + fishList.length,
        }

    }

    /**
     * 根据id删除对应的用户
     * @param {Number} uid
     */
    async deleteUserById(id) {
        // 删除前先删除地址
        await this.ctx.model.Address.destroy({ where: { member_id: id } });
        // 删除成功在删除用户
        return await this.ctx.model.Member.destroy({ where: { id } });
    }

    /**
     * 根据ID修改用户信息
     * @param {Number} id 用户ID
     * @param {Object} data 要修改的用户信息
     */
    async update(id, data) {
        const { Member } = this.ctx.model;
        const { username } = data;
        const andWhere = { id: { [Op.ne]: id } };
        let neenCheck = false;
        if (username) {
            neenCheck = true;
            andWhere.username = username;
        }

        if (neenCheck) {
            const userExists = await Member.findOne({
                attributes: ['id'],
                where: { [Op.and]: andWhere },
            });
            if (userExists) throw new Error('该账号已注册');
        }

        return await Member.update(data, { where: { id } });
    }
    /**
     * 更新用户密码
     * @param {Number} id 用户ID
     * @param {Object} data 新密码和旧密码
     */
    async updatePassword(id, data) {
        const { Member } = this.ctx.model;
        const user = await Member.findByPk(id);
        if (!user) {
            throw new Error('该手机号不存在');
        }

        // 旧密码是否有误, 正确就直接修改
        const isValid = bcrypt.compareSync(data.old_password, user.password);
        if (!isValid) {
            throw new Error('旧密码输入不正确');
        }
        user.password = data.new_password;
        return await user.save();
    }
    async findFishList(id) {
        // 查询鱼种
        const { Fish,FishCatch } = this.ctx.model;
        return Fish.findAll({
            // include种关联的FishCatch 为空也需要展示
            include: [
                {
                    model: FishCatch,
                    where: {
                        member_id: id,
                    },
                    required: false,
                }
            ]
        })
    }
    async findLureList(id) {
        // 查询鱼种
        const { Lure,FishCatch } = this.ctx.model;
        return Lure.findAll({
            // include种关联的FishCatch 为空也需要展示
            include: [
                {
                    model: FishCatch,
                    where: {
                        member_id: id,
                    },
                    required: false,
                }
            ]
        })
    }
    async day({ member_id, date }) {
        // 查当月的打龟、鱼获数据
        const { FishCatch, Turtle } = this.ctx.model;
        const start = dayjs(date).startOf('month').format('YYYY-MM-DD HH:mm:ss');
        const end = dayjs(date).endOf('month').format('YYYY-MM-DD HH:mm:ss');
        const fishList = await FishCatch.findAll({
            where: {
                member_id,
                create_time: {
                    [Op.between]: [start, end],
                }
            },
            include: [
                {
                    model: this.ctx.model.Fish,
                },
                {
                    model: this.ctx.model.Lure,
                }
            ]
        })
        console.log('fishList',fishList)
        const turtleList = await Turtle.findAll({
            where: {
                member_id,
                create_time: {
                    [Op.between]: [start, end],
                }
            }
        })
        // 打龟、鱼获的出勤天数
        const fishDays = fishList.reduce((prev, cur) => {
            const date = dayjs(cur.create_time).format('YYYY-MM-DD');
            if (!prev.includes(date)) {
                prev.push(date);
            }
            return prev;
        }, []);
        const turtleDays = turtleList.reduce((prev, cur) => {
            const date = dayjs(cur.create_time).format('YYYY-MM-DD');
            if (!prev.includes(date)) {
                prev.push(date);
            }
            return prev;
        }, []);
        // 总共出勤天数
        const days = [...fishDays, ...turtleDays].reduce((prev, cur) => {
            if (!prev.includes(cur)) {
                prev.push(cur);
            }
            return prev;
        }, []);
        return {
            fishDays: fishDays.length,
            turtleDays: turtleDays.length,
            days: days.length,
            fishList: fishList.map(item => {
                return {
                    date: dayjs(item.create_time).format('YYYY-MM-DD'),
                    info: '鱼获',
                    data: {
                        id: item.id,
                    },
                    ...item.dataValues,
                    create_time: dayjs(item.dataValues.create_time).format('YYYY-MM-DD HH:mm:ss'),
                }
            }),
            turtleList: turtleList.map(item => {
                return {
                    date: dayjs(item.create_time).format('YYYY-MM-DD'),
                    info: '打龟',
                    data: {
                        id: item.id,
                        type: '1'
                    },
                    ...item.dataValues,
                    create_time: dayjs(item.dataValues.create_time).format('YYYY-MM-DD HH:mm:ss'),
                }
            })
        }
    }

}

module.exports = UserService;
